package com.leyou.search.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.leyou.item.bo.SpuBo;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.SpecParam;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import com.leyou.pojo.PageResult;
import com.leyou.search.client.CategoryClient;
import com.leyou.search.client.GoodsClient;
import com.leyou.search.client.SpecificationClient;
import com.leyou.search.pojo.Goods;
import com.leyou.search.repository.GoodsRepository;
import com.leyou.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 项目: leyou
 *
 * @author 岩冰
 * @version 2018/10/11 8:47
 */
@Service
public class IndexService {


    @Autowired
    private GoodsRepository goodsRepository;
    @Autowired
    private GoodsClient goodsClient;
    @Autowired
    private CategoryClient categoryClient;
    @Autowired
    private SpecificationClient specificationClient;

    private ExecutorService pool = Executors.newFixedThreadPool(3);

    public void importGoods() throws InterruptedException {
        //先查询goodslient
        int page = 0;
        int rows = Integer.MAX_VALUE;
        PageResult<SpuBo> pageResult = goodsClient.querySpuByPage(null, true, page, rows);
        List<SpuBo> spuBoList = pageResult.getItems();
        // 对应的spuBoList需要全部封装到goods中
       spuBoList.forEach(this::Index);



    }

    private void Index(Spu spu) {
//         CountDownLatch countDownLatch = new CountDownLatch(3);
        Goods goods = new Goods();
//        pool.submit(() -> {
                //查询分类
            List<String> list = categoryClient.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            //查询品牌,标题里面都包含了品牌信息,所以不查

            goods.setAll(spu.getTitle()+ StringUtils.join(list," "));
//            countDownLatch.countDown();
//        });
        //查询sku,封装skus的json格式和price的集合

//        pool.submit(()->{
            List<Sku> skuList = goodsClient.querySkuBySpuId(spu.getId()).stream().filter(Sku::getEnable).collect(Collectors.toList());
            List<Long> prices = skuList.stream().map(Sku::getPrice).collect(Collectors.toList());
            List<Map> spusMap = skuList.stream().map(
                    sku -> {
                        HashMap<String, Object> skuMap = new HashMap<>();
                        skuMap.put("id",sku.getId());
                        skuMap.put("title",sku.getTitle());
                        skuMap.put("image", StringUtils.isBlank(sku.getImages()) ? "":sku.getImages().split(",")[0]);
                        skuMap.put("price",sku.getPrice());
                        return skuMap;
                    }
            ).collect(Collectors.toList());
            goods.setSkus(JsonUtils.serialize(spusMap));
            goods.setPrice(prices);
//                countDownLatch.countDown();
//        });

        //先查询出来所有cid对于的specparams
        //再根据通用和特有的值去对于
//        pool.submit(()->{

            List<SpecParam>specParamList = specificationClient.querySpecParams(null, spu.getCid3(), true, null);
            //查询到spudetail
            SpuDetail spuDetail = goodsClient.querySpuDetailById(spu.getId());

            Map<Long, String> genericSpec = JsonUtils.nativeRead(spuDetail.getGenericSpec(), new TypeReference<Map<Long, String>>() {});
            Map<Long, List<String>> specialSpec = JsonUtils.nativeRead(spuDetail.getSpecialSpec(), new TypeReference<Map<Long, List<String>>>() {});
            HashMap<String, Object> map = new HashMap<>();
            specParamList.forEach(specParam -> {
                Long id = specParam.getId();
                String name = specParam.getName();
                Object value = null;
                if (specParam.getGeneric()) {
                    //如果是通用的模板,通过id找到对应的值
                    value = genericSpec.get(id);

                    //只有公共的才好筛选,找到
                    if (specParam.getNumeric()) {
                        //如果是数组
                        if (value!=null) {
                            value = this.chooseSegment(value.toString(),specParam);
                        }
                    }
                } else  {
                    //特有的
                    value = specialSpec.get(id);
                }

                //判断是否为空,为空的话添加其他
                if (null==value) {
                    value = "其他";
                }
                map.put(name, value);
            });
            goods.setSpecs(map);
//            countDownLatch.countDown();
//        });
        //放到主线程等待区域
        goods.setBrandId(spu.getBrandId());
        goods.setCid1(spu.getCid1());
        goods.setCid2(spu.getCid2());
        goods.setCid3(spu.getCid3());
        goods.setCreateTime(spu.getCreateTime());
        goods.setSubTitle(spu.getSubTitle());
        goods.setId(spu.getId());
     /*   try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        goodsRepository.save(goods);
    }

    private Object chooseSegment(String val, SpecParam param) {

        //将val转换为数字
        double value = NumberUtils.toDouble(val);
        String[] segments = param.getSegments().split(",");
        String result = "其他";
        for (String segment : segments) {
            String[] strings = segment.split("-");
            double start= NumberUtils.toDouble(strings[0]);
            double end = Double.MAX_VALUE;
            if (strings.length==2) {
                //有上下边界
                end= NumberUtils.toDouble(strings[1]);
            }

            //如果是在范围内
            if (value>=start &&value<end) {
                if (strings.length == 1) {
                    result = strings[0] + param.getUnit() + "以上";
                } else if (start == 0) {
                    result = strings[1] + param.getUnit() + "以下";
                } else {
                    result = segment + param.getUnit();
                }
                //找到了就停
                break;
            }
        }

        return result;
    }


    public void createIndex(Long id) {
        Spu spu = this.goodsClient.querySpuBySpuId(id);
        if (spu==null) {
            System.out.println("为空");
            return;
        }
        if (spu.getSaleable()) {
            this.Index(spu);
        } else {
            this.deleteIndex(id);
        }
    }
    public void deleteIndex(Long id) {
        this.goodsRepository.deleteById(id);
    }
}
